/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stud.cp.user.userqueries;

import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import javax.ejb.Stateless;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import stud.cp.core.dbaccess.DAOException;
import stud.cp.core.plugins.PluginConst;
import stud.cp.core.plugins.PluginRouter;
import stud.cp.core.plugins.WrongPageRequest;
import stud.cp.user.dbaccess.OracleDAOFactory;
import stud.cp.user.dbaccess.PropertiesDAO;
import stud.cp.user.valueobjects.History;
import stud.cp.user.valueobjects.Property;
import stud.cp.user.valueobjects.PropertyGroup;
import stud.cp.user.valueobjects.User;

/**
 * Класс плагин, реализующий
 * бизнес логику для пользовательских
 * зарпосов к базе данных оружия.
 * @author Morfant
 */
@Stateless
public class UserQueriesPluginBean implements UserQueriesPluginLocal {

    /**
     * Фабрика DAO классов.
     */
    private OracleDAOFactory oracleDAOFactory = null;
    /**
     * Логгер.
     */
    private static Logger logger = Logger.getLogger("CPTNP");

    /**
     * Метод, реализующий основную бизнеслогику.
     * @param req Реквест.
     * @return Класс роутер.
     */
    @Override
    public PluginRouter perform(HttpServletRequest req) {
        String subaction = req.getParameter(PluginConst.SUBACTION);
        if ((subaction != null) && (!subaction.equals(""))) {
            try {
                oracleDAOFactory = new OracleDAOFactory();
                oracleDAOFactory.initialize();

                /* Список действий которые могут выполниться. */
                /*Список данных*/
                if (subaction.equals(PluginConst.GET_LIST)) {
                    return getListPage(req);
                }

                /* Старница с отчетом о количестве пользователей каждого типа. */
                if (subaction.equals(PluginConst.GET_USER_COUNT_BY_TYPE_PAGE)) {
                    return getUserCountByTypePage(req);
                }

                /* Старница с диалого выбора пользователя. */
                if (subaction.equals(PluginConst.GET_USER_SELECTOR_PAGE)) {
                    return getUserSelectorPage(req);
                }

                /* Старница с историей изменений данных пользователем.. */
                if (subaction.equals(PluginConst.GET_USER_CHAGE_SET_PAGE)) {
                    return getHistoryPageForUser(req);
                }

                /* Старница с выбором даты изменений.. */
                if (subaction.equals(PluginConst.GET_DATE_SELECTOR_PAGE)) {
                    return getDateSelectorPage(req);
                }

                /* Старница с изменениями по определенной дате.. */
                if (subaction.equals(PluginConst.GET_CHANGE_SET_FOR_DATE_PAGE)) {
                    return getChangeSetForDatePage(req);
                }

                /* Старница с выбором группы. */
                if (subaction.equals(PluginConst.GET_GROUP_SELECTOR_PAGE)) {
                    return getGroupSelectorPage(req);
                }

                /* Старница с свойствами определенной группы.. */
                if (subaction.equals(PluginConst.GET_PROPERTIES_FOR_GROUP_PAGE)) {
                    return getPropertiesForGroupPage(req);
                }

                /* Старница с выбором свойств. */
                if (subaction.equals(PluginConst.GET_PROPERTY_SELECTOR_PAGE)) {
                    return getPropertySelectorPage(req);
                }

                /* Старница с данными об количестве оружия определенного типа для свойства.. */
                if (subaction.equals(PluginConst.GET_WEAPON_COUNT_AND_TYPE_FOR_PROPERTY)) {
                    return getWeaponCountAndTypeForProperty(req);
                }

                /* Старница списочного выбора свойств.. */
                if (subaction.equals(PluginConst.GET_PROPERTY_LIST_SELECTOR_PAGE)) {
                    return getPropertyListSelectorPage(req);
                }

                /* Старница списочного выбора свойств.. */
                if (subaction.equals(PluginConst.GET_WEAPON_TYPES_FOR_PROPERTIES)) {
                    return getWeaponTypesForProperties(req);
                }

                /* Старница с выбором группы для оружия. */
                if (subaction.equals(PluginConst.GET_GROUP_SELECTOR_FOR_WEAPON_PAGE)) {
                    return getGroupSelectorForWeaponPage(req);
                }

                /* Старница с оружием и типами для группы свойств.. */
                if (subaction.equals(PluginConst.GET_WEAPON_COUNT_AND_TYPE_FOR_GROUP)) {
                    return getWeaponCountAndTypeForGroup(req);
                }

                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Действия для данного типа поддействия не найдено. Тип поддействия = " + subaction);
            } catch (DAOException ex) {
                logger.debug("Error due access to database. "
                        + "Plugin = PropertyGroupPluginBean. "
                        + "Subaction=" + subaction, ex);
                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Ошибка доступа к данным. " + ex.getMessage());
            } catch (WrongPageRequest ex) {
                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Данные из реквеста ошибочны :\n" + ex.getMessage());
            } finally {
                if (oracleDAOFactory != null) {
                    try {
                        oracleDAOFactory.cleanUp();
                    } catch (DAOException ex) {
                        logger.debug("Error due access to database. "
                                + "Plugin = PropertyGroupPluginBean. "
                                + "Subaction=" + subaction, ex);
                        req.setAttribute(PluginConst.ERROR_MESSAGE,
                                "Ошибка доступа к данным. " + ex.getMessage());
                    }
                }
            }
        } else {
            req.setAttribute(PluginConst.ERROR_MESSAGE,
                    "Тип поддействия не задан.");
        }
        return new PluginRouter("/errorpage.jsp");
    }

    /**
     * Метод, который позволяет получить
     * список данных запрашиваемого типа.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getListPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        return new PluginRouter("/UserQueries/QueriesTable.jsp");
    }

    /**
     * Метод, который позволяет получить
     * отчет по количеству пользователей каждого типа.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getUserCountByTypePage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        req.setAttribute(PluginConst.RESULT, oracleDAOFactory.getUserQueriesDAO().getUserCountByType());
        return new PluginRouter("/UserQueries/CountOfUserByType.jsp");
    }

    /**
     * Метод, который позволяет получить
     * список пользователей.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getUserSelectorPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        req.setAttribute(PluginConst.USERS_LIST, oracleDAOFactory.getUserDAO().getAll());
        return new PluginRouter("/UserQueries/UserSelector.jsp");
    }

    /**
     * Метод, который позволяет
     * просмотреть историю изменения данных об
     * оружии конкретного пользователя.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getHistoryPageForUser(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String user_id = req.getParameter(PluginConst.USER_ID);
        if (user_id != null) {
            User user =
                    oracleDAOFactory.getUserDAO().getById(new BigInteger(user_id));
            if (user != null) {
                List<History> weaponHistory =
                        oracleDAOFactory.getUserQueriesDAO().getAllHistoryForUser(user.getUserID());
                req.setAttribute(PluginConst.CURRENT_USER, user);
                req.setAttribute(PluginConst.HISTORY_LIST, weaponHistory);
                return new PluginRouter("/UserQueries/UserHistoryTable.jsp");
            } else {
                throw new WrongPageRequest("Пользователя с таким id=" + user_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID типа оружия не заданно.");
        }
    }

    /**
     * Метод, который позволяет получить
     * страницу с выбором даты изменений.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getDateSelectorPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        return new PluginRouter("/UserQueries/DateSelector.jsp");
    }

    /**
     * Метод, который позволяет
     * просмотреть историю изменения данных по определенной дате.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getChangeSetForDatePage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String dateInString = req.getParameter(PluginConst.SELECT_DATE);
        if (dateInString != null) {
            //Преобразование даты из строки в дату и т.п. действия.
            DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
            try {
                Date date = df.parse(dateInString);
                List<History> weaponHistory =
                        oracleDAOFactory.getUserQueriesDAO().getAllHistoryForDate(date);
                req.setAttribute(PluginConst.SELECT_DATE, dateInString);
                req.setAttribute(PluginConst.HISTORY_LIST, weaponHistory);
                return new PluginRouter("/UserQueries/DateHistoryTable.jsp");
            } catch (ParseException ex) {
                throw new WrongPageRequest("Формат даты не верен.");
            }


        } else {
            throw new WrongPageRequest("Дата не заданна.");
        }
    }

    /**
     * Метод, который позволяет получить
     * список групп для выбора одной.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getGroupSelectorPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        req.setAttribute(PluginConst.PROPERTY_GROUPS_LIST, oracleDAOFactory.getPropertyGroupsDAO().getAll());
        return new PluginRouter("/UserQueries/GroupSelector.jsp");
    }

    /**
     * Метод, который позволяет
     * просмотреть свойства для конкретной группы.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getPropertiesForGroupPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_group_id = req.getParameter(PluginConst.PROPERTY_GROUP_ID);
        if (property_group_id != null) {
            PropertyGroup propertyGroup =
                    oracleDAOFactory.getPropertyGroupsDAO().getById(new BigInteger(property_group_id));
            if (propertyGroup != null) {
                List<Property> propertiesList =
                        oracleDAOFactory.getUserQueriesDAO().
                        getAllPropertyForPropertyGroup(propertyGroup.getProperty_group_id());
                req.setAttribute(PluginConst.PROPERTY_GROUP, propertyGroup);
                req.setAttribute(PluginConst.PROPERTIES_LIST, propertiesList);
                return new PluginRouter("/UserQueries/PropertiesForGroup.jsp");
            } else {
                throw new WrongPageRequest("Группы с таким id=" + property_group_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID группы свойств не заданно.");
        }
    }

    /**
     * Метод, который позволяет получить
     * список свойств для выбора.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getPropertySelectorPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        req.setAttribute(PluginConst.PROPERTIES_LIST, oracleDAOFactory.getPropertiesDAO().getAll());
        return new PluginRouter("/UserQueries/PropertiesSelector.jsp");
    }

    /**
     * Метод, который позволяет
     * просмотреть число оружия определенного типа для свойства..
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getWeaponCountAndTypeForProperty(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_Id = req.getParameter(PluginConst.PROPERTY_ID);
        if (property_Id != null) {
            Property property =
                    oracleDAOFactory.getPropertiesDAO().getById(new BigInteger(property_Id));
            if (property != null) {
                req.setAttribute(PluginConst.PROPERTY, property);
                req.setAttribute(PluginConst.RESULT,
                        oracleDAOFactory.getUserQueriesDAO().getWeaponCountAndTypeForProperty(property.getProperty_id()));
                return new PluginRouter("/UserQueries/WeaponCountAndType.jsp");
            } else {
                throw new WrongPageRequest("Свойства с таким id=" + property_Id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID группы свойств не заданно.");
        }
    }

    /**
     * Метод, который позволяет получить
     * список свойств для выбора.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getPropertyListSelectorPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        req.setAttribute(PluginConst.PROPERTIES_LIST, oracleDAOFactory.getPropertiesDAO().getAll());
        return new PluginRouter("/UserQueries/PropertiesListSelector.jsp");
    }

    /**
     * Метод, который позволяет
     * просмотреть типы оружия для набора запрашиваемых свойств.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getWeaponTypesForProperties(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String[] property_Ids = req.getParameterValues(PluginConst.PROPERTIES_ID);
        if (property_Ids != null) {
            List<BigInteger> listOfIDs = new LinkedList<BigInteger>();
            int lenght = property_Ids.length;
            BigInteger value;
            for (int i = 0; i < lenght; i++) {
                value = new BigInteger(property_Ids[i]);
                listOfIDs.add(value);
            }
            List<Property> listOfProperty = oracleDAOFactory.getUserQueriesDAO().getAllPropertyForIDs(listOfIDs);
            if (listOfProperty.size() == listOfIDs.size()) {
                req.setAttribute(PluginConst.PROPERTIES_LIST, listOfProperty);
                req.setAttribute(PluginConst.RESULT,
                        oracleDAOFactory.getUserQueriesDAO().getWeaponTypeForProperties(listOfIDs));
                return new PluginRouter("/UserQueries/WeaponTypeForProperties.jsp");
            } else {
                throw new WrongPageRequest("Не все запрашиваемые свойства существуют. ");
            }
        } else {
            throw new WrongPageRequest("ID свойств не заданно.");
        }
    }

    /**
     * Метод, который позволяет получить
     * список групп для выбора одной.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getGroupSelectorForWeaponPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        req.setAttribute(PluginConst.PROPERTY_GROUPS_LIST, oracleDAOFactory.getPropertyGroupsDAO().getAll());
        return new PluginRouter("/UserQueries/GroupSelectorForWeapon.jsp");
    }

    /**
     * Метод, который позволяет
     * просмотреть число оружия определенного типа для группы..
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getWeaponCountAndTypeForGroup(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String property_group_id = req.getParameter(PluginConst.PROPERTY_GROUP_ID);
        if (property_group_id != null) {
            PropertyGroup property_group =
                    oracleDAOFactory.getPropertyGroupsDAO().getById(new BigInteger(property_group_id));
            if (property_group != null) {
                req.setAttribute(PluginConst.PROPERTY_GROUP, property_group);
                req.setAttribute(PluginConst.RESULT,
                        oracleDAOFactory.getUserQueriesDAO().getWeaponCountAndTypeForGroup(property_group.getProperty_group_id()));
                return new PluginRouter("/UserQueries/WeaponCountAndTypeForGroup.jsp");
            } else {
                throw new WrongPageRequest("Группы с таким id=" + property_group_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID группы свойств не заданно.");
        }
    }
}
